<?php

namespace addons\thirdwork\library;

use fast\Http;
use think\Cache;
use think\Session;

/**
 * 企业微信
 */
class Wechatwork
{
	const GET_TMP_AUTH_CODE_URL        = 'https://open.weixin.qq.com/connect/oauth2/authorize';
	const GET_USER_INFO_BYCODE_URL     = 'https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo';
	const GET_USER_URL                 = 'https://qyapi.weixin.qq.com/cgi-bin/user/get';
	const GET_ACCESS_TOKEN_URL         = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken';
	const GET_DEPARTMENT_LIST_URL      = 'https://qyapi.weixin.qq.com/cgi-bin/department/list';
	const GET_DEPARTMENT_MEMBER_URL    = 'https://qyapi.weixin.qq.com/cgi-bin/user/simplelist';
	const GET_DEPARTMENT_USER_LIST_URL = 'https://qyapi.weixin.qq.com/cgi-bin/user/list';
	const GET_USER_DETAIL_AFTER_AUTH   = 'https://qyapi.weixin.qq.com/cgi-bin/auth/getuserdetail';
	const SEND_MESSAGE_URL             = 'https://qyapi.weixin.qq.com/cgi-bin/message/send';
	const RECALL_MESSAGE_URL           = 'https://qyapi.weixin.qq.com/cgi-bin/message/recall';

	/**
	 * 配置信息
	 * @var array
	 */
	private $config = [];

	public function __construct($options = [])
	{
		if ($config = get_addon_config('thirdwork')['wechatwork']) {
			$this->config = array_merge($this->config, $config);
		}
		$this->config = array_merge($this->config, is_array($options) ? $options : []);
	}

	/**
	 * 获取authorize_url
	 */
	public function getAuthorizeUrl()
	{
		$state = md5(uniqid(rand(), TRUE));
		Session::set('state', $state);
		$request = [
			'appid'         => $this->config['corpid'],
			'redirect_uri'  => $this->config['callback'],
			'response_type' => 'code',
			'scope'         => 'snsapi_privateinfo',
			'state'         => $state,
			'agentid'       => $this->config['agentid'],
		];
		$url     = self::GET_TMP_AUTH_CODE_URL . '?' . http_build_query($request) . '#wechat_redirect';
		return $url;
	}

	/**
	 * 获取用户信息
	 * @param array $params
	 * @return array
	 */
	public function getUserInfo($params = [])
	{
		$params = $params ? $params : request()->get();
		if ((isset($params['state']) && $params['state'] == Session::get('state') && isset($params['code']))) {
			//用code换openid和unionid
			$request = [
				'access_token' => $this->getAccessToken(),
				'code'         => $params['code'],
			];
			$ret     = Http::get(self::GET_USER_INFO_BYCODE_URL, $request);
			$ret     = json_decode($ret, TRUE);
			if (!$ret || $ret['errcode']) {
				return ['errmsg' => '获取个人信息失败'];
			}
			$openid = '';
			// 非企业成员
			if (isset($ret['OpenId'])) {
				if (get_addon_config('thirdwork')['registerverify'] === '1') {
					return ['errmsg' => '你不是该企业的成员'];
				} else {
					$openid = $ret['OpenId'];
				}
			}
			// 企业成员
			if (isset($ret['UserId'])) {
				// 用userid查用户详情
				$request  = [
					'user_ticket' => $ret['user_ticket']
				];
				$request  = json_encode($request, JSON_UNESCAPED_UNICODE);
				$response = Http::post(self::GET_USER_DETAIL_AFTER_AUTH . '?access_token=' . $this->getAccessToken(), $request);
				$response = json_decode($response, TRUE);
				if (!$response || $response['errcode']) {
					return ['errmsg' => '获取成员详情失败'];
				}
				$userinfo             = $response ? $response : [];
				$userinfo['nickname'] = isset($userinfo['name']) ? $userinfo['name'] : '';
				$userinfo['avatar']   = isset($userinfo['avatar']) ? $userinfo['avatar'] : '';
			}

			$data = [
				'access_token'  => '',
				'refresh_token' => '',
				'expires_in'    => 0,
				'openid'        => $openid,
				'userinfo'      => $userinfo
			];
			return $data;
		}
		return ['errmsg' => '第三方平台授权失败'];
	}

	/**
	 * 获取access_token
	 * @return string
	 */
	public function getAccessToken()
	{
		$cache = Cache::get('wechatwork_access_token');
		if ($cache) {
			if (isset($cache['access_token']) && time() < $cache['expire_time']) {
				return $cache['access_token'];
			}
		}

		$request  = array(
			'corpid'     => $this->config['corpid'],
			'corpsecret' => $this->config['corpsecret'],
		);
		$response = Http::get(self::GET_ACCESS_TOKEN_URL, $request);
		$response = json_decode($response, TRUE);
		if (!$response['errcode']) {
			Cache::tag('thirdwork')->set('wechatwork_access_token', [
				'access_token' => $response['access_token'],
				'expire_time'  => time() + 7200
			]);
			return $response['access_token'];
		}
		return $response;
	}

	/**
	 * 获取部门列表
	 * @return array
	 */
	public function getDepartmentList($department_id = 0)
	{
		$request = ['access_token' => $this->getAccessToken()];
		if ($department_id > 0) {
			$request['id'] = $department_id;
		}
		$response = Http::get(self::GET_DEPARTMENT_LIST_URL, $request);
		$response = json_decode($response, TRUE);
		if ($response['department']) {
			return ['code' => 1, 'data' => $response['department']];
		}
		return ['code' => 0, 'msg' => $response['errmsg'], 'data' => $response];
	}

	/**
	 * 获取部门成员详情
	 * @return array
	 */
	public function getDepartmentUserList($department_id)
	{
		$request  = [
			'access_token'  => $this->getAccessToken(),
			'department_id' => $department_id,
			'fetch_child'   => 0
		];
		$response = Http::get(self::GET_DEPARTMENT_USER_LIST_URL, $request);
		$response = json_decode($response, TRUE);
		if (isset($response['userlist'])) {
			$data = [];
			foreach ($response['userlist'] as $v) {
				$data[] = array(
					'userid'   => $v['userid'],
					'name'     => $v['name'],
					'order'    => $v['order'][0] ?? 0,
					'position' => $v['position'],
					'active'   => $v['status'] === 1 //激活状态: 1=已激活，2=已禁用，4=未激活，5=退出企业。
				);
			}
			return ['code' => 1, 'data' => $data];
		}
		return ['code' => 0, 'msg' => $response['errmsg'], 'data' => $response];
	}

	/**
	 * 获取部门成员人数
	 * @return array
	 */
	public function getDepartmentUserCount()
	{
		$params   = request()->get();
		$request  = array(
			'access_token'  => $this->getAccessToken(),
			'department_id' => $params['department_id'],
			'fetch_child'   => 0
		);
		$response = Http::get(self::GET_DEPARTMENT_MEMBER_URL, $request);
		$response = json_decode($response, TRUE);
		if (!$response['errcode'] && isset($response['userlist'])) {
			return ['code' => 1, 'data' => count($response['userlist'])];
		}
		return ['code' => 0, 'msg' => $response['errmsg'], 'data' => $response];
	}

	/**
	 * 获取部门成员userid列表
	 * @return array 成员userid数组
	 */
	public function getDepartmentUserIds()
	{
		$params   = request()->get();
		$request  = array(
			'access_token'  => $this->getAccessToken(),
			'department_id' => $params['department_id'],
			'fetch_child'   => 0
		);
		$response = Http::get(self::GET_DEPARTMENT_MEMBER_URL, $request);
		$response = json_decode($response, TRUE);
		if (!$response['errcode'] && isset($response['userlist'])) {
			$ids = array();
			foreach ($response['userlist'] as $v) {
				$ids[] = $v['userid'];
			}
			return ['code' => 1, 'data' => $ids];
		}
		return ['code' => 0, 'msg' => $response['errmsg'], 'data' => $response];
	}

	/**
	 * 发送图文消息
	 * @param $data
	 * @param $touser //成员ID列表（消息接收者，多个接收者用‘|’分隔，最多支持1000个）。
	 * @param $toparty //部门ID列表，多个接收者用‘|’分隔，最多支持100个。
	 * @param $totag //标签ID列表，多个接收者用‘|’分隔，最多支持100个。
	 * @return array
	 */
	public function sendNewsMessage($data, $touser = '', $toparty = '', $totag = '')
	{
		$request = [
			'msgtype' => 'news',
			'agentid' => $this->config['agentid'],
			'news'    => [
				'articles' => $data
			]
		];
		if (!empty($touser)) {
			$request['touser'] = $touser;
		}
		if (!empty($toparty)) {
			$request['toparty'] = $toparty;
		}
		if (!empty($totag)) {
			$request['totag'] = $totag;
		}
		$request  = json_encode($request, JSON_UNESCAPED_UNICODE);
		$response = Http::post(self::SEND_MESSAGE_URL . '?access_token=' . $this->getAccessToken(), $request);
		$response = json_decode($response, TRUE);
		if (!$response['errcode']) {
			return ['code' => 1, 'msg' => $response['errmsg'], 'request' => $request, 'response' => json_encode($response, JSON_UNESCAPED_UNICODE)];
		}
		return ['code' => 0, 'msg' => $response['errmsg'], 'request' => $request, 'response' => json_encode($response, JSON_UNESCAPED_UNICODE)];
	}

	/**
	 * 发送文字消息
	 * @param $content
	 * @param $touser //成员ID列表（消息接收者，多个接收者用‘|’分隔，最多支持1000个）。
	 * @param $toparty //部门ID列表，多个接收者用‘|’分隔，最多支持100个。
	 * @param $totag //标签ID列表，多个接收者用‘|’分隔，最多支持100个。
	 * @return array
	 */
	public function sendTextMessage($content, $touser = '', $toparty = '', $totag = '')
	{
		$request = [
			'msgtype' => 'text',
			'agentid' => $this->config['agentid'],
			'text'    => [
				'content' => $content
			]
		];
		if (!empty($touser)) {
			$request['touser'] = $touser;
		}
		if (!empty($toparty)) {
			$request['toparty'] = $toparty;
		}
		if (!empty($totag)) {
			$request['totag'] = $totag;
		}
		$request  = json_encode($request, JSON_UNESCAPED_UNICODE);
		$response = Http::post(self::SEND_MESSAGE_URL . '?access_token=' . $this->getAccessToken(), $request);
		$response = json_decode($response, TRUE);
		if (!$response['errcode']) {
			return ['code' => 1, 'msg' => $response['errmsg'], 'request' => $request, 'response' => json_encode($response, JSON_UNESCAPED_UNICODE)];
		}
		return ['code' => 0, 'msg' => $response['errmsg'], 'request' => $request, 'response' => json_encode($response, JSON_UNESCAPED_UNICODE)];
	}

	public function sendCardMessage($formuser, $touser)
	{
		$request = [
			'msgtype'       => 'template_card',
			'agentid'       => $this->config['agentid'],
			'template_card' => [
				'card_type'               => 'button_interaction',
				'main_title'              => [
					'title' => '【待办提醒】您有新的申请信息',
					'desc'  => ''
				],
				'horizontal_content_list' => [
					['keyname' => '消息名称', 'value' => '工资条 - 重置识别码'],
					['keyname' => '申请员工', 'value' => $formuser['nickname']],
					['keyname' => '所属部门', 'value' => $formuser['department_name']],
					['keyname' => '提交时间', 'value' => datetime(time())],
				],
				'task_id'                 => time(), //任务id，同一个应用任务id不能重复，只能由数字、字母和“_-@”组成，最长128字节
				'button_list'             => [
					['text' => '同意', 'style' => 1, 'key' => 'yes_' . $formuser['id']],
					['text' => '拒绝', 'style' => 4, 'key' => 'no_' . $formuser['id']]
				]
			]
		];
		if (!empty($touser)) {
			$request['touser'] = $touser;
		}
		if (!empty($toparty)) {
			$request['toparty'] = $toparty;
		}
		if (!empty($totag)) {
			$request['totag'] = $totag;
		}
		$request  = json_encode($request, JSON_UNESCAPED_UNICODE);
		$response = Http::post(self::SEND_MESSAGE_URL . '?access_token=' . $this->getAccessToken(), $request);
		$response = json_decode($response, TRUE);
		if (!$response['errcode']) {
			return ['code' => 1, 'msg' => $response['errmsg'], 'request' => $request, 'response' => json_encode($response, JSON_UNESCAPED_UNICODE)];
		}
		return ['code' => 0, 'msg' => $response['errmsg'], 'request' => $request, 'response' => json_encode($response, JSON_UNESCAPED_UNICODE)];
	}

	public function recallMessage($msgid)
	{
		$request  = [
			'msgid' => $msgid
		];
		$request  = json_encode($request, JSON_UNESCAPED_UNICODE);
		$response = Http::post(self::RECALL_MESSAGE_URL . '?access_token=' . $this->getAccessToken(), $request);
		$response = json_decode($response, TRUE);
		if (!$response['errcode']) {
			return ['code' => 1, 'msg' => $response['errmsg'], 'request' => $request, 'response' => json_encode($response, JSON_UNESCAPED_UNICODE)];
		}
		return ['code' => 0, 'msg' => $response['errmsg'], 'request' => $request, 'response' => json_encode($response, JSON_UNESCAPED_UNICODE)];
	}
}
